import { MessageType, WebSocketMessage, ConnectionStatus, WebSocketConfig as WS_CONFIG } from './types.js';
import MessageHandler from './messageHandlers.js';
import {getUserId } from '../utils/storage';

/**
 * WebSocket连接管理器
 * 负责WebSocket连接的创建、维护、重连和消息处理
 */
class WebSocketManager {
  constructor() {
    this.ws = null;
    this.status = ConnectionStatus.DISCONNECTED;
    this.reconnectAttempts = 0;
    this.heartbeatTimer = null;
    this.reconnectTimer = null;
    this.messageQueue = [];
    this.messageHandlers = new Map();
    this.onStatusChangeCallbacks = [];
    this.isManualClose = false;
    this.connectionId = null;
    this.isRegistered = false;
    
    // 注册默认消息处理器
    this.registerDefaultHandlers();
  }

  /**
   * 注册默认消息处理器
   */
  registerDefaultHandlers() {
    // 创建消息处理器实例
    this.messageHandler = new MessageHandler(this);
    
    // 注册默认消息处理器 - 修复参数传递问题
    this.messageHandlers.set(MessageType.REGISTER_SUCCESS, (message) => {
      this.messageHandler.handleRegisterSuccess(message);
    });
    this.messageHandlers.set(MessageType.PONG, (message) => {
      this.messageHandler.handlePong(message);
    });
    this.messageHandlers.set(MessageType.FORCE_LOGOUT, (message) => {
      this.messageHandler.handleForceLogout(message);
    });
  }

  /**
   * 注册自定义消息处理器
   * @param {MessageType} messageType 消息类型
   * @param {Function} handler 处理器函数
   */
  registerHandler(messageType, handler) {
    this.messageHandlers.set(messageType, handler);
  }

  /**
   * 连接状态变化回调
   * @param {Function} callback 回调函数
   */
  onStatusChange(callback) {
    this.onStatusChangeCallbacks.push(callback);
  }

  /**
   * 更新连接状态
   * @param {ConnectionStatus} newStatus 新状态
   */
  updateStatus(newStatus) {
    if (this.status !== newStatus) {
      this.status = newStatus;
      this.onStatusChangeCallbacks.forEach(callback => callback(newStatus));
    }
  }

  /**
   * 建立WebSocket连接
   * @returns {Promise<boolean>} 连接是否成功
   */
  async connect() {
    try {
      // 如果已有连接，先关闭
      if (this.ws) {
        this.disconnect();
      }

      this.isManualClose = false;
      this.updateStatus(ConnectionStatus.CONNECTING);

      // 构建WebSocket URL（不需要token参数）
      const wsUrl = WS_CONFIG.SERVER_URL;
      this.ws = new WebSocket(wsUrl);

      return new Promise((resolve) => {
        this.ws.onopen = () => {
          console.log('WebSocket连接成功');
          this.reconnectAttempts = 0;
          this.updateStatus(ConnectionStatus.CONNECTED);
          this.processMessageQueue();
          
          // 连接成功后自动发送注册消息
          this.sendRegisterMessage();
          resolve(true);
        };

        this.ws.onmessage = (event) => {
          this.handleIncomingMessage(event);
        };

        this.ws.onclose = (event) => {
          console.log('WebSocket连接关闭:', event.code, event.reason);
          this.cleanup();
          
          if (!this.isManualClose && this.reconnectAttempts < WS_CONFIG.maxReconnectAttempts) {
            // this.scheduleReconnect();
            console.log('我这里不重连了。');
          } else {
            this.updateStatus(ConnectionStatus.DISCONNECTED);
          }
          
          resolve(false);
        };

        this.ws.onerror = (error) => {
          console.error('WebSocket连接错误:', error);
          this.updateStatus(ConnectionStatus.ERROR);
          resolve(false);
        };

        // 设置连接超时
        setTimeout(() => {
          if (this.status === ConnectionStatus.CONNECTING) {
            console.error('WebSocket连接超时');
            this.ws.close();
            resolve(false);
          }
        }, WS_CONFIG.connectionTimeout);
      });
    } catch (error) {
      console.error('WebSocket连接异常:', error);
      this.updateStatus(ConnectionStatus.ERROR);
      return false;
    }
  }

  /**
   * 断开WebSocket连接
   */
  disconnect() {
    this.isManualClose = true;
    this.cleanup();
    
    if (this.ws) {
      this.ws.close(1000, 'Manual disconnect');
      this.ws = null;
    }
    
    this.updateStatus(ConnectionStatus.DISCONNECTED);
  }

  /**
   * 清理资源
   */
  cleanup() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
    
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
  }

  /**
   * 开始心跳检测
   */
  startHeartbeat() {
    this.heartbeatTimer = setInterval(() => {
      if (this.status === ConnectionStatus.CONNECTED) {
        this.sendHeartbeat();
      }
    }, WS_CONFIG.heartbeatInterval);
  }

  /**
   * 发送心跳包
   */
  sendHeartbeat() {
    const heartbeatMessage = new WebSocketMessage(MessageType.PING, { timestamp: Date.now() });
    this.sendMessage(heartbeatMessage);
  }

  /**
   * 重置心跳计时器（用于PONG响应）
   */
  resetHeartbeat() {
    // 心跳计时器由setInterval管理，不需要重置
    // 这个方法是为了兼容messageHandlers中的调用
    console.log('收到PONG响应，心跳正常');
  }

  /**
   * 安排重连
   */
  scheduleReconnect() {
    this.reconnectAttempts++;
    const delay = Math.min(
      WS_CONFIG.reconnectBaseDelay * Math.pow(WS_CONFIG.reconnectBackoff, this.reconnectAttempts - 1),
      WS_CONFIG.maxReconnectDelay
    );

    console.log(`将在 ${delay}ms 后尝试第 ${this.reconnectAttempts} 次重连`);
    this.updateStatus(ConnectionStatus.RECONNECTING);

    this.reconnectTimer = setTimeout(() => {
      this.connect();
    }, delay);
  }

  /**
   * 立即重连
   */
  reconnect() {
    console.log('立即重连WebSocket');
    this.cleanup();
    this.isManualClose = false;
    this.connect();
  }

  /**
   * 处理接收到的消息
   * @param {MessageEvent} event WebSocket消息事件
   */
  handleIncomingMessage(event) {
    try {
      const messageData = JSON.parse(event.data);
      const message = WebSocketMessage.fromObject(messageData);
      
      console.log('收到WebSocket消息:', message);

      // 查找对应的消息处理器 - 支持多个处理器
      const handlers = [];
      
      // 获取特定类型的处理器
      const specificHandler = this.messageHandlers.get(message.type);
      if (specificHandler) {
        handlers.push(specificHandler);
      }
      
      // 获取通用处理器（处理所有消息类型）
      const genericHandler = this.messageHandlers.get('*');
      if (genericHandler) {
        handlers.push(genericHandler);
      }

      if (handlers.length > 0) {
        handlers.forEach(handler => handler(message));
      } else {
        console.warn(`未注册的消息类型处理器: ${message.type}`);
      }
    } catch (error) {
      console.error('消息解析错误:', error, event.data);
    }
  }

  /**
   * 发送消息
   * @param {WebSocketMessage} message 要发送的消息
   * @returns {boolean} 发送是否成功
   */
  sendMessage(message) {
    if (this.status !== ConnectionStatus.CONNECTED || !this.ws) {
      console.warn('WebSocket未连接，消息加入队列:', message);
      this.messageQueue.push(message);
      return false;
    }

    try {
      const messageStr = JSON.stringify(message.toObject());
      this.ws.send(messageStr);
      return true;
    } catch (error) {
      console.error('发送消息失败:', error);
      this.messageQueue.push(message);
      return false;
    }
  }

  /**
   * 处理消息队列
   */
  processMessageQueue() {
    while (this.messageQueue.length > 0 && this.status === ConnectionStatus.CONNECTED) {
      const message = this.messageQueue.shift();
      this.sendMessage(message);
    }
  }

  /**
   * 获取当前连接状态
   * @returns {ConnectionStatus} 连接状态
   */
  getStatus() {
    return this.status;
  }

  /**
   * 获取重连尝试次数
   * @returns {number} 重连尝试次数
   */
  getReconnectAttempts() {
    return this.reconnectAttempts;
  }

  /**
   * 检查是否已连接
   * @returns {boolean} 是否已连接
   */
  isConnected() {
    return this.status === ConnectionStatus.CONNECTED;
  }

  /**
   * 发送注册消息（连接建立后自动发送）
   * @param {Object} userInfo 用户信息
   */
  sendRegister(userInfo) {
    const registerMessage = new WebSocketMessage(MessageType.REGISTER, userInfo);
    this.sendMessage(registerMessage);
  }

  /**
   * 发送注册消息（从localStorage获取userId）
   */
  sendRegisterMessage() {
    // 从localStorage获取userId
    const userId = getUserId();
    console.log('现在要发起注册消息,从localStorage获取userId:', userId);
    if (userId) {
      const registerMessage = new WebSocketMessage(MessageType.REGISTER, userId);
      this.sendMessage(registerMessage);
      console.log('发送注册消息:', userId);
    } else {
      console.warn('未找到userId，无法发送注册消息');
    }
  }

  /**
   * 设置连接ID
   * @param {string} connId 连接ID
   */
  setConnectionId(connId) {
    this.connectionId = connId;
    this.isRegistered = true;
    console.log('WebSocket注册成功，连接ID:', connId);
    
    // 注册成功后启动心跳
    this.startHeartbeat();
  }
}

// 创建单例实例
const webSocketManager = new WebSocketManager();

export default webSocketManager;
export { WebSocketManager };
